package cc.linker.steplink.crm.task;


import cc.linker.steplink.crm.commons.http.HttpService;
import cc.linker.steplink.crm.commons.lock.RedisLock;
import cc.linker.steplink.crm.merchant.util.DateUtil;
import cc.linker.steplink.crm.response.GlobalException;
import cc.linker.steplink.crm.service.*;

import com.mongodb.util.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.text.ParseException;
import java.util.*;


/**
 * 智能客户专员机器人推送任务
 */

@Slf4j
@Component
public class ClientRobotTask {

    @Value("${system.scrm.wxpushurl}")
    private String url;

    @Autowired
    private IMarketRobotService marketRobotService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private IClientRobotService clientRobotService;

    @Autowired
    private ISysConfig sysConfigService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HttpService httpService;

    private static final String WXPUSHLIST_LOCK = "wxpushlist_lock";
    private static final String WXPUSHLIST = "wxpushlist";


    /**
     * 客户专员机器人第一次推送
     *
     * @throws ParseException
     */
    @RedisLock("ClientRobotPush_yx")
    @Scheduled(cron = "30 0/20 * * * ?")
//    @Scheduled(cron = "0/10 * * * * ?")
    public void clientRobotPushTime() throws Exception {
        //获取智能客户专员机器人开关打开的所有机构id
        Map<String, String> param = new HashMap<>();
        param.put("confName", "clientRobotSwitch");
        param.put("confValue", "1");
        List<Map<String, String>> orgIdList = marketRobotService.getOrgIdByNameAndValue(param);
        if (null != orgIdList && orgIdList.size() > 0) {
            for (Map<String, String> val : orgIdList) {
                String orgId = val.get("orgId");

                Map<String, Object> orgFunction = customerService.getOrgFunctionOrgId(orgId);
                if (orgFunction == null || StringUtils.isEmpty(orgFunction.get("cusNum"))) {
                    continue;
                }
                if (!StringUtils.isEmpty(orgFunction.get("cusExpireDate"))) {
                    // 判断时间是否到期
                    Long expireTime = dateToStamp(orgFunction.get("cusExpireDate").toString() + " 00:00:00");
                    Long nowTime = System.currentTimeMillis();
                    if(nowTime>expireTime){
                        continue;
                    }
                }
                //获取该机构的每日推送时间
                String clientRobotStartTime = sysConfigService.getSysConfByName(orgId, "clientRobotStartTime");
                if (null == clientRobotStartTime) {
                    clientRobotStartTime = "08:00:00";
                }
                //获取机构文章库的标签   逗号拼接的标签ID
                String labelIds = clientRobotService.getArticleLabelByOrgIdAndType(orgId, "client");
                if (StringUtils.isEmpty(labelIds)) {
                    continue;
                }
                Integer limitNum = 5000 * (Integer.parseInt(orgFunction.get("cusNum").toString()));
                //获取当前机构下需要分析的客户
                List<Map<String, Object>> customerList = customerService.getRobotUser(orgId, limitNum);
                for (Map<String, Object> cu : customerList) {
                    //推送頻次
                    Integer pushLevel = Integer.parseInt(cu.get("customerPushrateLevel").toString());
                    String openid = (String)cu.get("openid");
                    String token = (String)cu.get("token");
                    String customerId = (String)cu.get("customerId");
                    //若取出的用户没有token和openid 跳出
                    if (StringUtils.isEmpty(openid) || StringUtils.isEmpty(token) || StringUtils.isEmpty(customerId)) {
                        continue;
                    }

                    //更新用户被机器人维护过的状态 用於統計人數
                    customerService.updateRobotActive(customerId, "client");

                    //推送列表中有该用户的未推送记录，跳出
                    String lockValue = token + openid;
                    Boolean isLock = stringRedisTemplate.opsForSet().isMember(WXPUSHLIST_LOCK, lockValue);
                    if (isLock) {
                        continue;
                    }

                    // 比较标签 选出用户无的标签
                    String[] labelIdsArray = labelIds.split(",");
                    List<String> label = new ArrayList<>();
                    Collections.addAll(label, labelIdsArray);
                    // 分析用户 获取用户拥有的标签
                    String customerLables = customerService.getLabelsByOpenidAndToken(openid, token);
                    if (!StringUtils.isEmpty(customerLables)) {
                        String[] customerLableArray = customerLables.split(",");
                        List<String> customerLable = new ArrayList<>();
                        Collections.addAll(customerLable, customerLableArray);
                        label.removeAll(customerLable);
                    }
                    if (label.size() < 1) {
                        continue;
                    }
                    // 随机取一个 推送带有该标签的文章
                    Random random = new Random();
                    String oneLabelId = label.get(random.nextInt(label.size()));
                    if (StringUtils.isEmpty(oneLabelId)) {
                        continue;
                    }
                    // 获取带有该标签的所有文章 集合
                    List<String> articles = clientRobotService.getArticleIdByLabel(oneLabelId, orgId);
                    // 获取用户已推送的文章集合
                    List<String> pushArticles = clientRobotService.getPushArticleId(openid, token);
                    articles.removeAll(pushArticles);
                    if (articles.size() < 1) {
                        continue;
                    }
                    // 随机选取一篇文章
                    Random random1 = new Random();
                    String oneArticleId = articles.get(random1.nextInt(articles.size()));
                    if (StringUtils.isEmpty(oneArticleId)) {
                        continue;
                    }
                    Map<String, String> oneArticle = clientRobotService.getOneArticle(oneArticleId, orgId);


                    // 根据推送频次 计算下次推送时间
                    long nextPushTime;
                    Calendar calendar1 = Calendar.getInstance();
                    String[] split1 = clientRobotStartTime.split(":");
                    if (split1.length != 3) {
                        throw GlobalException.build("时间不对");
                    }
                    //今天的推送时间
                    calendar1.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split1[0]));
                    calendar1.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
                    calendar1.set(Calendar.SECOND, Integer.valueOf(split1[2]));
                    long today = calendar1.getTimeInMillis() / 1000;
                    nextPushTime = today;
                    //取用户的最后一次推送时间
                    String lastPushTime = clientRobotService.getLastPushTimeByOpenIdAndToken(openid, token);
                    if (!StringUtils.isEmpty(lastPushTime)) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        Date parse = simpleDateFormat.parse(lastPushTime);
                        Calendar calendar2 = Calendar.getInstance();
                        calendar2.setTime(parse);
                        calendar2.add(Calendar.DAY_OF_MONTH, pushLevel);
                        long lastTime = calendar2.getTimeInMillis() / 1000;
                        if (lastTime > today) {
                            continue;
                        }
                    }
                    // 执行推送入列
                    Map<String, Object> pushData = new HashMap<>();
                    pushData.put("token", token);
                    pushData.put("openid", openid);
                    pushData.put("title", oneArticle.get("articleTitle"));
                    pushData.put("desc", oneArticle.get("articleDesc"));
                    pushData.put("url", oneArticle.get("articleUrl"));
                    pushData.put("image", oneArticle.get("articleImage"));
                    pushData.put("articleId", oneArticle.get("articleId"));
                    pushData.put("time", nextPushTime);
                    pushData.put("orgId", orgId);
                    pushData.put("type", "client");

                    stringRedisTemplate.opsForSet().add(WXPUSHLIST, JSON.serialize(pushData));
                    stringRedisTemplate.opsForSet().add(WXPUSHLIST_LOCK, lockValue);
                }
            }
        }
    }


    /**
     * 生成维护记录
     *
     * @throws Exception
     */
    @RedisLock("RobotStatistics")
    @Scheduled(cron = "10 0/50 * * * ?")
    public void robotStatistics() throws Exception {
        //获取昨天时间 年月日格式
        String tallyTime = new SimpleDateFormat("yyyy-MM-dd").format((System.currentTimeMillis()) - 86400000L);
        String endTime = new SimpleDateFormat("yyyy-MM-dd").format((System.currentTimeMillis()));
        List<Map<String, String>> orgIdList = clientRobotService.getOrgIds();
        if (null != orgIdList && orgIdList.size() > 0) {
            for (Map<String, String> val : orgIdList) {
                String orgId = val.get("orgId");
                String robotSwitch = val.get("switch");
                Map<String, Object> param = new HashMap<>();
                Map<String, Object> orgFunction = customerService.getOrgFunctionOrgId(orgId);
                if (orgFunction == null) {
                    continue;
                }
                //client 机器人是否开启
                if (robotSwitch.contains("clientRobotSwitch:1") || robotSwitch.contains("marketRobotSwitch:1")) {
                    //活跃度
                    String activity = clientRobotService.getActivity(orgId);
                    String tranRate = "0.00";

                    param.put("tallyTime", endTime);
                    param.put("activity", activity);
                    param.put("orgId", orgId);
                    if (robotSwitch.contains("clientRobotSwitch:1")) {
                        if (StringUtils.isEmpty(orgFunction.get("cusNum"))) {
                            continue;
                        }
                        if (!StringUtils.isEmpty(orgFunction.get("cusExpireDate"))) {
                            // 判断时间是否到期
                            Long expireTime = dateToStamp(orgFunction.get("cusExpireDate").toString() + " 00:00:00");
                            Long nowTime = System.currentTimeMillis();
                            if(nowTime>expireTime){
                                continue;
                            }
                        }
                        Integer limitNum = 5000 * (Integer.parseInt(orgFunction.get("cusNum").toString()));
                        //维护人数
                        Integer maintainNum = clientRobotService.getMaintainNum(orgId);
                        maintainNum = maintainNum > limitNum ? limitNum : maintainNum;
                        param.put("maintainNum", maintainNum);

                        //client机器人的推送时间
                        String startTimes = sysConfigService.getSysConfByName(orgId, "clientRobotStartTime");
                        startTimes = StringUtils.isEmpty(startTimes) ? "08:00:00" : startTimes;
                        String clientRobotStartTime = tallyTime.concat(" ").concat(startTimes);
                        String clientRobotEndTime = endTime.concat(" ").concat(startTimes);
                        //阅读时长
                        Integer readTime = clientRobotService.getReadTime(orgId, clientRobotStartTime, clientRobotEndTime);
                        //关注
                        Integer followNum = clientRobotService.getFollowNum(orgId, clientRobotStartTime, clientRobotEndTime);
                        //取消关注
                        Integer unfollowNum = clientRobotService.getUnfollowNum(orgId, clientRobotStartTime, clientRobotEndTime);
                        param.put("readTime", String.format("%.2f", (double) readTime / 3600));
                        param.put("tranRate", tranRate);
                        param.put("followNum", followNum);
                        param.put("unfollowNum", unfollowNum);
                        param.put("type", "client");
                        clientRobotService.addRobotStatistics(param);
                    }
                    if (robotSwitch.contains("marketRobotSwitch:1")) {
                        if (StringUtils.isEmpty(orgFunction.get("marNum"))) {
                            continue;
                        }
                        if (!StringUtils.isEmpty(orgFunction.get("marExpireDate"))) {
                            // 判断时间是否到期
                            Long expireTime = dateToStamp(orgFunction.get("marExpireDate").toString() + " 00:00:00");
                            Long nowTime = System.currentTimeMillis();
                            if(nowTime>expireTime){
                                continue;
                            }
                        }
                        Integer limitNum = 5000 * (Integer.parseInt(orgFunction.get("cusNum").toString()));
                        //维护人数
                        Integer maintainNum = clientRobotService.getMaintainNum(orgId);
                        maintainNum = maintainNum > limitNum ? limitNum : maintainNum;
                        param.put("maintainNum", maintainNum);

                        //market机器人的推送时间
                        String startTimes = sysConfigService.getSysConfByName(orgId, "marketRobotStartTime");
                        startTimes = StringUtils.isEmpty(startTimes) ? "08:00:00" : startTimes;
                        String marketRobotStartTime = tallyTime.concat(" ").concat(startTimes);
                        String marketRobotEndTime = endTime.concat(" ").concat(startTimes);

                        //阅读时长
                        Integer readTime = 0;
                        //转化率
                        Integer orderCount = clientRobotService.getTranRate(orgId, marketRobotStartTime, marketRobotEndTime);
                        Integer touchNum = clientRobotService.getTouchNum(orgId, marketRobotStartTime, marketRobotEndTime);
                        tranRate = touchNum < 1 ? "0.00" : String.format("%.2f", (double) orderCount / touchNum * 100);

                        //关注
                        Integer followNum = clientRobotService.getFollowNum(orgId, marketRobotStartTime, marketRobotEndTime);
                        //取消关注
                        Integer unfollowNum = clientRobotService.getUnfollowNum(orgId, marketRobotStartTime, marketRobotEndTime);
                        param.put("readTime", readTime);
                        param.put("tranRate", tranRate);
                        param.put("followNum", followNum);
                        param.put("unfollowNum", unfollowNum);
                        param.put("type", "market");
                        clientRobotService.addRobotStatistics(param);
                    }
                }
            }
        }
    }

    /*
     * 将时间转换为时间戳
     */
    public static Long dateToStamp(String s) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(s);
        return  date.getTime();
    }
}
